package com.brillilab.service.core.experiments.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.brillilab.common.entity.PageVo;
import com.brillilab.dao.mapper.experiments.ExperimentProduceMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.kit.KitEnum.KitType;
import com.brillilab.domain.po.experiments.ExperimentProduce;
import com.brillilab.domain.po.experiments.ExperimentProduceAttr;
import com.brillilab.domain.po.kit.SampleTemplate;
import com.brillilab.domain.vo.experiments.ExperimentProduceListVo;
import com.brillilab.domain.vo.kit.SampleInfoVo;
import com.brillilab.domain.vo.kit.SampleTemplateGroupVo;
import com.brillilab.service.core.experiments.IExperimentProduceAttrService;
import com.brillilab.service.core.experiments.IExperimentProduceService;
import com.brillilab.service.core.kit.ISampleTemplateService;
import com.brillilab.service.core.system.IDictService;

@Service
@Transactional
public class ExperimentProduceServiceImpl implements IExperimentProduceService {

	@Resource
	private ExperimentProduceMapper experimentProduceMapper;
	@Resource
	private IDictService dictService;
	@Resource
	private ISampleTemplateService sampleTemplateService;
	@Resource
	private IExperimentProduceAttrService experimentProduceAttrService;

	@Override
	public List<ExperimentProduce> selectByExperimentIds(List<Long> experimentIds) {
		LambdaQueryWrapper<ExperimentProduce> wrapper = new LambdaQueryWrapper<>();
		wrapper.in(ExperimentProduce::getExperimentId, experimentIds);
		return experimentProduceMapper.selectList(wrapper);
	}

	@Override
	public ExperimentProduce selectById(Long id) {
		return experimentProduceMapper.selectById(id);
	}

	@Override
	public ExperimentProduce insert(ExperimentProduce produce) {
		experimentProduceMapper.insert(produce);
		return produce;
	}

	@Override
	public List<ExperimentProduce> selectProduceList(Long experimentId, boolean isNotNullStepId) {
		LambdaQueryWrapper<ExperimentProduce> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ExperimentProduce::getExperimentId, experimentId);
		if (isNotNullStepId) {
			wrapper.isNotNull(ExperimentProduce::getExperimentStepId);
		}
		return experimentProduceMapper.selectList(wrapper);
	}

	@Override
	public int selectProduceCount(Long experimentId) {
		LambdaQueryWrapper<ExperimentProduce> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ExperimentProduce::getExperimentId, experimentId);
		return experimentProduceMapper.selectCount(wrapper);
	}

	@Override
	public int updateAliasBatch(List<ExperimentProduce> updateProduces) {
		if (CollectionUtils.isNotEmpty(updateProduces)) {
			return experimentProduceMapper.updateAliasBatch(updateProduces);
		}
		return 0;
	}

	@Override
	public List<ExperimentProduce> selectList(List<Long> produceIds) {
		if (CollectionUtils.isNotEmpty(produceIds)) {
			return experimentProduceMapper
					.selectList(new LambdaQueryWrapper<ExperimentProduce>().in(ExperimentProduce::getId, produceIds));
		}
		return new ArrayList<>();
	}

	@Override
	public List<ExperimentProduceListVo> produceList(Long experimentId) {
		return experimentProduceMapper.produceList(experimentId);
	}

	@Override
	public SampleInfoVo getProduceDetails(Long id, Long labMemberId) {

		ExperimentProduce produce = this.selectById(id);

		Map<Integer, String> unitMap = dictService.getUnitMap();
		Map<Integer, String> zoneMap = dictService.getZoneMap();
		Map<Long, String> reagentTypeMap = dictService.getReagentTypeMap(produce.getLabId());
		SampleInfoVo vo = new SampleInfoVo();
		vo.setReagentTypeId(produce.getReagentTypeId());
		vo.setName(produce.getName());
		vo.setReagentTypeName(reagentTypeMap.get(produce.getReagentTypeId()));
		vo.setKitType(KitType.ONE.getValue());
		vo.setUnit(produce.getUnit());
		vo.setUnitName(unitMap.get(produce.getUnit()));
		vo.setZone(produce.getZone());
		vo.setZoneName(zoneMap.get(produce.getZone()));
		vo.setSize(produce.getSize());
		vo.setMultiple(produce.getMultiple());
		vo.setItemNo(produce.getItemNo());
		vo.setCompanyId(produce.getCompanyId());
		vo.setCompany(produce.getCompany());
		vo.setRemark(produce.getRemark());
		if(produce.getSize()!=null){
			String specName = produce.getSize().stripTrailingZeros().toPlainString() + vo.getUnitName();
			if (produce.getMultiple() > 1)
				specName += "*" + produce.getMultiple();
			vo.setSpecName(specName);
		}

		// 组装属性值
		List<SampleTemplateGroupVo> groupList = sampleTemplateService.getSampleTemplateGroup(produce.getReagentTypeId(),
				produce.getLabId(), labMemberId);
		List<ExperimentProduceAttr> attrList = experimentProduceAttrService.selectList(produce.getId());
		if (!CollectionUtils.isEmpty(groupList)) {
			Map<Long, List<ExperimentProduceAttr>> attrMapp = attrList.stream()
					.collect(Collectors.groupingBy(ExperimentProduceAttr::getSampleTemplateId));
			groupList.forEach(groupVo -> {
				List<SampleTemplate> templateList = groupVo.getTemplateList();
				if (!CollectionUtils.isEmpty(templateList)) {
					for (Iterator<SampleTemplate> iterator = templateList.iterator(); iterator.hasNext();) {
						SampleTemplate template = iterator.next();
						List<ExperimentProduceAttr> list = attrMapp.get(template.getId());
						if (!CollectionUtils.isEmpty(list)) {
							ExperimentProduceAttr attr = list.get(0);
							if (StringUtils.isNotBlank(attr.getAttrValue())
									|| BoolEnum.FALSE.getValue().equals(template.getIsHide())) {
								template.setSampleAttrId(attr.getId());
								template.setAttrValue(attr.getAttrValue());
								template.setIsHide(BoolEnum.FALSE.getValue());
							}
						}
						if (BoolEnum.TRUE.getValue().equals(template.getIsHide())) {
							iterator.remove();
						}
					}
				}
			});
			for (Iterator<SampleTemplateGroupVo> iterator = groupList.iterator(); iterator.hasNext();) {
				SampleTemplateGroupVo groupVo = iterator.next();
				if (CollectionUtils.isEmpty(groupVo.getTemplateList()) && !"基础属性".equals(groupVo.getGroupName())) {
					iterator.remove();
				}
			}
		}
		vo.setSampleAttrList(groupList);
		return vo;
	}

	@Override
	public PageVo<ExperimentProduce> produceList(Long experimentId, int pageNum, int pageSiz) {
		LambdaQueryWrapper<ExperimentProduce> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ExperimentProduce::getExperimentId, experimentId);
		IPage<ExperimentProduce> selectPage = experimentProduceMapper.selectPage(new Page<>(pageNum,pageSiz),wrapper);
		return new PageVo<ExperimentProduce>(selectPage);
	}
}
